package com.smh.demo1.a02;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author shiminghui
 * @date 2025/4/9 21:25
 * @description: TODO
 */
public class TestBeanFactory {

    /*
     * internalConfigurationAnnotationProcessor beanFactoryPostProcessor, 补充了一些bean的定义
     * internalAutowiredAnnotationProcessor beanPostProcessor,  针对bean的各生命周期提供一些扩展 如@Autowired,@Value等
     * internalCommonAnnotationProcessor beanPostProcessor, 处理@Resource,@PostConstruct等注解
     * */


    public static void main(String[] args) {
        // 创建bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 创建bean定义
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
                .genericBeanDefinition(Config.class)
                .setScope("singleton")
                .getBeanDefinition();
        // 注册bean定义
        beanFactory.registerBeanDefinition("config", beanDefinition);

        // 注册注解配置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // 调用 beanFactory 处理器
        Map<String, BeanFactoryPostProcessor> beansOfType = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        beansOfType.forEach((k, v) -> {
            System.out.println("beanFactoryProcessor :" + v);
            v.postProcessBeanFactory(beanFactory); // 调用处理器
        });

        // 添加bean后处理器
        Map<String, BeanPostProcessor> beansOfType1 = beanFactory.getBeansOfType(BeanPostProcessor.class);
        beansOfType1.forEach((k, v) -> {
            beanFactory.addBeanPostProcessor(v); // 添加处理器
        });

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        // 当然,我们可以主观调用,将单例bean实例化
        beanFactory.preInstantiateSingletons();
        System.out.println("===========================================================================");
        // 只有在getBean的时候才会真正实例化bean
        Bean2 bean2 = (Bean2) beanFactory.getBean("bean2");
        System.out.println(bean2.getBean1());
        System.out.println(bean2.getInter());
    }

    interface Inter {

    }

    @Configuration
    static class Config {

        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }

        @Bean
        public Bean3 bean3() {
            return new Bean3();
        }

        @Bean
        public Bean4 bean4() {
            return new Bean4();
        }
    }

    static class Bean1 {

    }

    static class Bean2 {

        @Autowired
        private Bean1 bean1;

        // 测试@Autowired 有多个实现时,会报错
        @Resource(name = "bean4")
        @Autowired
        private Inter bean3;

        public Bean1 getBean1() {
            return bean1;
        }

        public Inter getInter() {
            return bean3;
        }

    }

    static class Bean3 implements Inter {

    }

    static class Bean4 implements Inter {

    }
}
